﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using EasyStep.Data.Entities;

namespace WPF.TestEditor.Controls
{
    public partial class TestDataConstantEditor : UserControlBase
    {
        public event EventHandler DataChanged;

        private const string constPrefix = "c:";
        private System.Timers.Timer timer = new System.Timers.Timer(250);
        public Common.DynamicACCollection AutoCompleteHelper { get; set; }
        private TestData _Data;
        public TestData Data
        {
            get { return _Data; }            
            set {
                _Data = value==null? new TestData():value;
                txtData.Text = _Data.Value;
                DataChanged(this,new EventArgs());
            }
        }
        public TestDataConstantEditor()
        {
            InitializeComponent();
            txtData.PreviewTextInput += new TextCompositionEventHandler(txtData_PreviewTextInput);
            txtData.AddHandler(TextBox.TextInputEvent, new TextCompositionEventHandler(txtData_TextInput), true);
            
            txtData.LostFocus += new RoutedEventHandler(txtData_LostFocus);
            txtData.GotFocus += new RoutedEventHandler(txtData_GotFocus);
            timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
        }


        void txtData_GotFocus(object sender, RoutedEventArgs e)
        {
            if (txtData.Text == DefaultText)
                txtData.Text ="";
        }

        void txtData_LostFocus(object sender, RoutedEventArgs e)
        {
            if (string.IsNullOrEmpty(txtData.Text))
                txtData.Text = DefaultText;
        }

        
        private Action onTimer;
        void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            timer.Stop();
            if (onTimer != null)
            {
                var method = onTimer;
                onTimer = null;
                Dispatcher.Invoke(method);
            }
        }
        
        public static readonly DependencyProperty DefaultTextProperty = DependencyProperty.Register("DefaultText", typeof(string), typeof(TestDataConstantEditor));
        public string DefaultText
        {
            get { return (string)GetValue(DefaultTextProperty); }
            set { SetValue(DefaultTextProperty, value); }
        }
        public static readonly DependencyProperty IsRequireProperty = DependencyProperty.Register("IsRequire", typeof(bool), typeof(TestDataConstantEditor));
        public bool IsRequire
        {
            get { return (bool)GetValue(IsRequireProperty); }
            set { SetValue(IsRequireProperty, value); }
        }
        private AutoCompleteWindow completionWindow;

        void txtData_PreviewTextInput(object sender, TextCompositionEventArgs e)
        {
            if (e.Text.Length > 0 && completionWindow != null)
            {
                var key = e.Text[0];
                if (!char.IsLetterOrDigit(key) && key != ',' && key != '=' && key != ' ' && key != ':')
                {
                    // Whenever a non-letter is typed while the completion window is open,
                    // insert the currently selected element.
                    completionWindow.CompletionList.RequestInsertion(e);
                }
                else
                {
                    var text = txtData.Text + e.Text;
                    if (completionWindow.StartOffset > -1)
                        text = text.Substring(completionWindow.StartOffset);
                    completionWindow.CompletionList.SelectItem(text);                    
                }
            }
        }

        void txtData_TextInput(object sender, TextCompositionEventArgs e)
        {
            if (txtData.Text.Length > 0 && AutoCompleteHelper != null && completionWindow == null)
            {
                completionWindow = AutoCompleteHelper.BuildList(txtData, () => new AutoCompleteWindow(txtData));
                if (completionWindow == null) return;
                completionWindow.Show();
                txtData.Focus();                
                completionWindow.Closed += delegate
                {
                    completionWindow = null;
                };
            }
        }
        private void txtData_TextChanged(object sender, TextChangedEventArgs e)
        {            
            onTimer = () =>
            {                
                timer.Stop();
                ValidateTextEditor(txtData.Text, (d) => _Data=d);                
                DataChanged(this, null);
            };
            timer.Start();           
        }
        /// <summary>
        /// needs to get data from text editor, validate it
        /// </summary>      
        /// <returns></returns>
        public bool ValidateTextEditor(string controlText, Action<TestData> ondata)
        {
            var result = !string.IsNullOrEmpty(controlText);
            var data = new TestData() { Value = (controlText ?? "").Trim() };
            if (data.Value.StartsWith(constPrefix))
            {
                var cname = data.Value.Remove(0, constPrefix.Length);
                data.Constant = TestDataContext.ConstantsManager.Get(cname);
                if (data.Constant != null) data.ConstId = data.Constant.Id;
                else
                {
                    //if (AutoConstantGeneration || MessageBox.Show("Do you want automatically generate constant with name: " + cname + "?", "Save Constant Dialog", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                    //{
                    //    Data.Constant = DataContext.ConstantsManager.GetOrCreateConst(cname, cname, Guid.Empty);
                    //    if (Data.Constant != null) Data.ConstId = Data.Constant.Id;
                    //}
                }
            }
            ondata(data);
            return result;
        }

        private void ConstPicker_Click(object sender, RoutedEventArgs e)
        {
            var pw = (this.ParenWindow as Window);
            var constName = txtData.Text.Trim();
            constName = constName.StartsWith(constPrefix, StringComparison.OrdinalIgnoreCase) ? constName.Remove(0, constPrefix.Length) : constName;
            var curData = new TestConst() { Name=constName};
            var constPicker = new ConstantPicker(TestDataContext, "Constant Editor", curData, (result) =>
            {
                txtData.Focus();
                txtData.Text=string.Concat(constPrefix, result.Name);
                txtData.SelectionStart = txtData.Text.Length;
                var existing=TestDataContext.ConstantsManager.Get(result.Name);
                if(existing==null)
                    TestDataContext.ConstantsManager.Create(result);
            });
            pw.Opacity = 0.25;            
            pw.ShowInTaskbar = false;
            constPicker.ShowDialog();
            pw.Opacity = 1;
            pw.ShowInTaskbar = true;
            constPicker.Close();
            constPicker = null;
        }

        
    }
}
